(function($){

    var prefix = "data-wyx-"//标签前缀,用户可以自行修改
    //支持的标签,用户可以自行添加
    var checkData = ["for", "each", "if", "elif","else", 'bind',"text", "value", "src", "class", "style", "href", "onclick", "onchange"];
    //自定义函数,用户可以自行添加
    var funcs = {
        formatDate:function(time, fmt){
            var date = new Date(time);
            var o = {
                "M+": date.getMonth() + 1, //月份
                "d+": date.getDate(), //日
                "H+": date.getHours(), //小时
                "m+": date.getMinutes(), //分
                "s+": date.getSeconds(), //秒
                "q+": Math.floor((date.getMonth() + 3) / 3), //季度
                "S": date.getMilliseconds() //毫秒
            };
            if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
            for (var k in o)
                if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
            return fmt;
        }
    }


    /**
     *
     * 欢迎阅读下面代码
     *
     */
    var dPool = {};//页面的数据
    var htmlPool = [];//页面元素对象
    var regNumber = /^[0-9]+(\.[0-9]+)?$/;
    //检查元素是否有系统标签
    var checkLabel = function(that){
        for(var i=0;i<checkData.length;i++){
            if(that.attr(prefix+checkData[i])){
                return true;
            }
        }
        return false;
    }
    //初始化标签
    var initTargetInfo = function(that, hPool){
        var data = {key:[],type:[],that:null,placeholder:null,thatContent:null,show:true,prev:null,next:null,list:[],index:0};
        data.that = that;
        data.placeholder = $('<i style="display: none"></i>');//元素占位
        data.thatContent = $('<div style="display: none"></div>');
        data.html = that.prop("outerHTML");
        //key type show

        for(var i=0;i<checkData.length;i++){
            var key = that.attr(prefix+checkData[i]);
            if(key){
                key = key.trim();
                var type = checkData[i];
                that.removeAttr("data-wyx-"+type);
                data.key[data.key.length] = key;
                data.type[data.type.length] = type;
                if(type == 'if'){
                    data.show = false;
                } else if(type == 'else' || type == 'elif'){//找到上一级的if
                    var prevThat = that.prev();
                    if(prevThat.length>0){
                        $.each(hPool, function(i2, v2){
                            if(prevThat.is(v2.placeholder) && (v2.type == 'if' || v2.type == 'elif')){
                                data.prev = v2;
                                v2.next = data;
                            } else {//如果上一级不是if 或elif 则永久隐藏
                                data.show = false;
                            }
                        });
                    }
                    data.show = false;
                } else if(type == 'for' || type == 'each'){
                    data.show = false;
                } else if(type == 'bind'){
                    var tagName = that.prop("tagName").toLowerCase();
                    if(tagName == 'input' || tagName == 'textarea' || tagName == 'select'){
                        var type = that.attr("type");
                        if(type == 'text' || tagName == 'textarea'){
                            that.bind('input propertychange', function() {
                                var poolData = getThatPoolData($(this), hPool);
                                var bindIndex = poolData.type.indexOf("bind");
                                if(bindIndex != -1){
                                    var k = poolData.key[bindIndex];
                                    k = k.replace(/^[\{]{1}/, "").replace(/[\}]{1}$/, "");
                                    setDataValue(k, dPool, this.value);
                                }

                            });
                        } else if(type == 'checkbox' || type == 'radio' || tagName == 'select'){
                            that.bind('change', function() {
                                var poolData = getThatPoolData($(this), hPool);
                                var bindIndex = poolData.type.indexOf("bind");
                                if(bindIndex != -1){
                                    var k = poolData.key[bindIndex];
                                    k = k.replace(/^[\{]{1}/, "").replace(/[\}]{1}$/, "");
                                    var value = [];
                                    var tagName = that.prop("tagName").toLowerCase();
                                    if(tagName == 'select'){
                                        $(this).find("option:selected").each(function(){
                                            value[value.length] = this.value;
                                        });
                                    } else {
                                        var name = $(this).attr("name");
                                        var type = $(this).attr("type");

                                        $("input[name='"+name+"'][type='"+type+"']:checked").each(function(){
                                            value[value.length] = this.value;
                                        });
                                    }
                                    setDataValue(k, dPool, value);
                                }

                            });
                        }
                    }

                }
            }
        }
        if(!data.show){
            //that.hide();
            data.that.before(data.placeholder);
            data.thatContent.append(data.that);
        }
        if(data.type.indexOf("for") != -1 ||data.type.indexOf("each") != -1){

        }
        handledPoolSon(data, dPool, null, hPool);
        return data;
    }


    var setDataValue = function(key, data, v){
        var value  = {};
        $.extend(value, data);

        var dataList = [data];
        var ks = key.trim().split(/[.|\[|\]]{1,2}/);
        for(var i=0;i<ks.length;i++){
            var k = ks[i];
            value = getdPoolValue(k, value);
            if(!value){
                value = {};
            }
            if(ks.length-1 == i){
                dataList[dataList.length] = v;
            } else {
                dataList[dataList.length] = value;
            }

        }
        for(var i=0;i<dataList.length-1;i++){
            var k = ks[i];
            dataList[i][k]=dataList[i+1]
        }
        var newData = {};
        newData[ks[0]] = dPool[ks[0]];
        $.setData(newData);

    }


    //加载子元素
    var loadChildren = function(that, hPool){
        that.children().each(function(){
            var forFlag = checkParentFor($(this), hPool);
            if(checkLabel($(this)) && !forFlag){
                var data = initTargetInfo($(this), hPool);
                hPool[hPool.length] = data;
                if(data.type[0] != 'for' && data.type[0] != 'each'){
                    loadChildren($(this), hPool);
                }
            } else {
                loadChildren($(this), hPool);
            }

        });
    }


    var getThatPoolData = function(that, hPool){
        var data = null;
        $.each(hPool, function(i, v){
            if(that.is(v.that)){
                data = v;
                return data;
            }
        })
        return data;
    }

    var checkParentFor = function(that, hPool){
        var parentThat = that.parent();
        var retFlag = false;
        if(parentThat.length == 1){
            $.each(hPool, function(i, v){
                if(parentThat.is(v.that)){
                    if(v.type[0] == 'for' || v.type[0] == 'each'){
                        retFlag= true;
                    } else {
                        retFlag = checkParentFor(parentThat);
                    }
                }
            })
        } else {
            retFlag = false;
        }
        return retFlag;
    }

    var setData = function(data){
        $.extend(dPool, data);
        $.each(htmlPool, function(i, v){
            //过滤不必要的渲染
            if(checkUpdateHPoll(v.key, data) || v.type.indexOf("else") != -1 || v.type.indexOf("elif") != -1  || v.type.indexOf("if") != -1){
                //渲染数据
                handledPoolSon(v, dPool, null, htmlPool);
            }
        });
    }

    var checkUpdateHPoll = function(keys, data){
        for(var i=0;i<keys.length;i++){
            var key = keys[i];
            var reg = /\{(.+?)\}/g;
            if(reg.test(key)){
                value = "";
                var z = key.match(reg);
                var retFlag = false;
                for(var i=0;i<z.length;i++){
                    var k = z[i].replace(/^[\{]{1}/, "").replace(/[\}]{1}$/, "");
                    retFlag = checkUpdateHPoll([k], data) || retFlag;
                }
                return retFlag;
            }

            reg = /[\(|\)|,|\.|&|\||!|=|>|<|:|+|-|*|/]{1,2}/g
            var bes = key.split(reg);
            var z = key.match(reg);
            if(z == ':'){//for
                if(bes[1]){
                    return checkAttrKey(bes[1].trim() ,data)
                }
            } else {
                for(var j=0;j<bes.length;j++){
                    if(checkAttrKey(bes[j] ,data)){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    var checkAttrKey = function(key, data){
        var regFlag = false;
        $.each(data, function(k,v){
            if(k == key.trim()){
                regFlag = true;
                return;
            }
        });
        return regFlag;
    }

    var removeLabel = function(that, type){
        that.removeAttr("data-wyx-"+type);
    }
    //if elseif else 判断是否要显示
    var if_elseif_else = function(data, hPool){
        if(data.prev){
            if(data.prev.show){
                return false;
            } else{
                return if_elseif_else(data.prev, hPool);
            }
        } else {
            return true;
        }

    }

    var if_next = function(data, hPool){
        if(data.next){
            handledPoolSon(data.next, dPool, null, hPool);
            if_next(data.next, hPool);
        }
    }


    var getdPoolValueUnion = function(key, data){
        var value = {};
        $.extend(value, dPool, data);
        return getdPoolValue(key, value);
    }

    //对象取值
    var getdPoolValue = function(key, data){
        if(key == "''" || key == null){
            return '';
        }
        var key = key.trim();

        if(key == "+" || key == "-" || key == "*" || key == "/" ){
            return key;
        }

        var value = {};


        //{} 取值
        var reg = /\{(.+?)\}/g;
        if(reg.test(key)){
            value = key;
            var z = key.match(reg);
            for(var i=0;i<z.length;i++){
                var k = z[i].replace(/^[\{]{1}/, "").replace(/[\}]{1}$/, "");
                var v = getdPoolValue(k, data);
                if(z[i] != value){
                    value = value.replace(z[i], v==null?"":v);
                } else {
                    value  = v;
                }

            }
            //布尔
            if(value == 'true'){
                value= true;
            } else if(value == 'false'){
                value= false;
            }
            return value;
        }

        //取''值
        if(/^'[^']+'$/.test(key)){
            var key2 =  key.replace(/'/g, "").trim();
            return key2;
        }

        //自定义方法运算
        reg = /\$\.\w+\([^\(]*\)/g;
        if(reg.test(key)){
            var z = key.match(reg);
            for(var i=0;i< z.length;i++){
                var newZ = z[i].replace("$.", "").replace("(", ",").replace(")", "");
                var newZSons = newZ.split(",");
                var v = funcs[newZSons[0]];
                var funValues = [];
                for(var j=0;j<newZSons.length;j++){
                    if(j > 0 && newZSons[j] !== ''){
                        funValues[funValues.length] = getdPoolValue(newZSons[j], data);
                    }

                }
                var val = "";
                if(v) val = v.apply(null, funValues);
                key = key.replace(z[i], "'"+val+"'");
            }
            return getdPoolValue(key, data);
        }


        //() 括号运算
        reg = /\(([^\(])+?\)/g;
        if(reg.test(key)){
            value = key;
            var z = key.match(reg);
            var bes = key.split(reg);
            for(var i=0;i<z.length;i++){
                var k = z[i].replace(/^[\(]{1}/, "").replace(/[\)]{1}$/, "");
                var v = getdPoolValue(k, data);
                if(v == null){
                    v = "";
                }
                if(z[i] != value){
                    value = value.replace(z[i], "'"+v+"'");
                    value =getdPoolValue(value, data);
                } else {
                    value  = v;
                }

            }
            //布尔
            if(value == 'true'){
                value= true;
            } else if(value == 'false'){
                value= false;
            }
            return value;
        }

        //三目运算
        reg = /[?|:]{1}/g
        var z = key.match(reg);
        var bes = key.split(reg);
        if(z && z.length == 2 && z[0] == "?" && z[1] == ":"){
            if(getdPoolValue(bes[0], data)){
                return getdPoolValue(bes[1], data);
            } else {
                return getdPoolValue(bes[2], data);
            }
        }

        //&& ||
        reg = /[&|\|]{2}/g
        z = key.match(reg);
        if(z){
            value = false;
            var bes = key.split(reg);
            for(var i=0;i<bes.length;i++){
                if(i>0){
                    if(z[i-1] == "&&"){
                        value = value && getdPoolValueUnion(bes[i], data)
                    } else if(z[i-1] == "||"){
                        value = value || getdPoolValueUnion(bes[i], data)
                    }

                } else {
                    value = getdPoolValueUnion(bes[i], data);
                }
            }
            return value;
        }


        z = key.match(/[==,===,>,<,>=,<=]{1,3}|[!=]{2}/);
        if(z){
            var be = key.split(z);
            var b = be[0].trim();
            var e = be[1].trim();
            var bValue = getdPoolValueUnion(b, data);
            var eValue = getdPoolValueUnion(e, data);
            bValue = /0/.test(bValue)?"0":bValue;
            eValue = /0/.test(eValue)?"0":eValue;

            bValue = bValue==null?'':bValue;
            eValue = eValue==null?'':eValue;
            if(z=="==" && bValue==eValue){
            } else if(z=='===' && bValue===eValue){
            } else if(z=='!=' && bValue!=eValue){
            } else if(regNumber.test(bValue) && regNumber.test(eValue)){
                if(z=='>' && bValue>eValue){
                } else if(z=='<' && bValue<eValue){
                } else if(z=='>=' && bValue>=eValue){
                } else if(z=='<=' && bValue<=eValue){
                } else {
                    return false;
                }
            } else {
                return false;
            }
            return true;
        }


        var stringValues = [];
        reg = /'([^'])+?'/g;
        var z = key.match(reg);
        if(z){
            for(var i=0;i<z.length;i++){
                var k = z[i].replace(/'/g, "");
                stringValues[stringValues.length] = k;
                key = key.replace(z[i], "{"+i+"}")
            }
        }
        //加减乘除
        reg = /[+|\-|\*|\/]{1}/g
        z = key.match(reg);
        if(z){
            var bes = key.split(reg);
            for(var i=0;i<bes.length;i++){
                var v2 = null;
                reg = /\{(\d+?)\}/g;
                if(reg.test(bes[i])) {
                    var k = bes[i].replace(/^[\{]{1}/, "").replace(/[\}]{1}$/, "");
                    v2 = stringValues[k];
                } else {
                    v2 = getdPoolValue(bes[i], data);
                }

                v2 = (v2==null?'':v2);

                if(i>0){
                    if(v2 == '' && !isNaN(value)){
                        v2 = 0;
                    } else if(value == '' && !isNaN(v2)){
                        value = 0;
                    }
                    if(z[i-1] == "+") {
                        value = value + v2
                    } else if(z[i-1] == "-"){
                        value = value - v2
                    } else if(z[i-1] == "*"){
                        value = value * v2
                    } else if(z[i-1] == "/"){
                        value = value / v2;
                    }
                } else {
                    value = v2;
                }
            }
            return value;
        }


        //如果是数值直接取出
        if(regNumber.test(key)){
            return parseFloat(key);
        }
        //布尔
        if(key == 'true'){
            return true;
        } else if(key == 'false'){
            return false;
        }

        if(data){
            $.extend(value, data);
        } else {
            $.extend(value, dPool);
        }


        //如果有!则直接运算成boolean
        if(key.indexOf("!") == 0){
            var newKey = key.replace(/^!/, "");
            var value = getdPoolValue(newKey, data);
            if(value){
                return false;
            } else {
                return true;
            }
        }


        var ks = key.trim().split(".");
        for(var i2=0;i2<ks.length;i2++){
            var v2 = ks[i2];
            if(value != null){
                var reg = /\[\d+\]/;
                if(reg.test(v2)){
                    if(value[v2.match(/\w+/)]){
                        value = value[v2.match(/\w+/)][v2.match(/[\d+]/)]
                    } else {
                        value = null;
                    }
                } else {
                    value = value[v2];
                }
            }
        };



        if(Array.isArray(value)){
            return value;
        }

        //如果是数值直接取出
        if(regNumber.test(value)){
            return parseFloat(value);
        }


        return value;
    }


    var for_ = function(data, sonData, hPool){
        var valData = {};
        $.extend(valData, sonData);
        var key = data.key[0];
        key = key.replace(/^[\{]{1}/, "").replace(/[\}]{1}$/, "");
        var type = data.type[0];
        if(type == 'for'){
            for(var j=0;j<data.list.length;j++){
                data.list[j].remove();
            }
            data.list = [];
            data.index = 0;
        }

        var bes = key.split(":");
        var kName = bes[0].split(",")[0];
        var indexName = bes[0].split(",")[1];
        var list = getdPoolValue(bes[1], valData);
        if(list != null && list.length>0){
            for(var j=0;j<list.length;j++){
                valData[kName.trim()] = list[j];//取得当前值
                if(indexName){
                    valData[indexName.trim()] = data.index;//取得index
                }
                handledPoolSon(data, valData, false, hPool);//渲染父元素
                var that = data.that.clone();

                if(data.show || data.type.indexOf("if") == -1){
                    that.css("display", "")
                    data.placeholder.before(that);
                    data.list[data.list.length] = that;
                    data.index ++;
                }
                data.that.hide();
                var hPoolSon = [];
                loadChildren(that, hPoolSon);
                for(var h=0;h<hPoolSon.length;h++){
                    handledPoolSon(hPoolSon[h], valData, null, hPoolSon);
                    if(hPoolSon[h].type[0]=='for' || hPoolSon[h].type[0]=='each'){
                        for_(hPoolSon[h], valData, hPoolSon);
                    }
                }

            }
        } else if(list == null){
            for(var j=0;j<data.list.length;j++){
                data.list[j].remove();
            }
            data.list = [];
            data.index = 0;
        }
    }


    //数据赋值 iffor 是否加载for
    var handledPoolSon = function(data, sonData, iffor, hPool){
        var dataT = data.that;//当前对象
        for(var i=0;i<data.key.length;i++){
            var key = data.key[i];
            var type = data.type[i];
            if(type == 'if'){
                data.show = getdPoolValueUnion(data.key[i], sonData);

            } else if(type == 'elif'){
                data.show = if_elseif_else(data, hPool);
                if(data.show){
                    data.show = getdPoolValueUnion(data.key[i], sonData);
                }

            } else if(type == 'else'){
                data.show = if_elseif_else(data, hPool);

            } else if(type == 'for' || type == 'each'){
                if(iffor == null || iffor){
                    for_(data, dPool);
                    return;
                }

            } else{
                //对象取值
                var value = getdPoolValueUnion(key, sonData);
                if(type == 'bind') {
                    if(value === null)value = "";
                    var tagName = dataT.prop("tagName").toLowerCase();
                    if (tagName == 'input' || tagName == 'textarea') {
                        var type = dataT.attr("type");
                        if (tagName == 'textarea' || tagName == 'TEXTAREA') {
                            dataT.html(value);
                        } else if (type == 'text') {
                            dataT.attr("value", value);
                        } else if (type == 'checkbox' || type == 'radio') {
                            if (Array.isArray(value)) {
                                $.each(value, function (i2, v2) {
                                    if (dataT.val() == v2) {
                                        dataT.prop("checked", true);
                                    } else {
                                        //dataT.prop("checked", false);
                                    }
                                });
                            }

                        }
                    } else if (tagName == 'select') {
                        if (Array.isArray(value)) {
                            $.each(value, function (i2, v2) {
                                dataT.find("option[value='" + v2 + "']").prop("selected", true);
                            });
                        }

                    }

                }else if(type == 'text'){
                    if(value === undefined) return;
                    if(value === null) value = "";
                    dataT.html(value);
                } else{
                    if(value === undefined) return
                    if(value === null) value = "";
                    dataT.attr(type, value);
                }
            }

        }
        if(data.type.indexOf("if") != -1 || data.type.indexOf("elif") != -1  || data.type.indexOf("else") != -1){
            if_next(data, hPool);
            if(data.show && data.type.indexOf("for") == -1 && data.type.indexOf("each") == -1){
                data.placeholder.after(data.that);
            } else {
                data.thatContent.append(data.that);
            }
        }


    }

    $.extend({
        setData:function(opt) {
            return setData(opt);
        }
    });
    var options = {};

    $(document).ready(function(){
        for(var k in window){
            try{
                var v = window[k];
                if(typeof(v) == 'function'){
                    funcs[k] = v;
                }
            }catch(e){}
        }
        console.log(funcs)

        loadChildren($("html"),htmlPool);


        //setData({});
    });
})(jQuery);
